package edu.hawaii.wicket.page.scheduler;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
/**
 * Class for handling calendar settings.
 * @author Gerolf Seitz
 * https://github.com/gseitz
 */
public class FullCalendarSettings implements Serializable { 

  private static final long serialVersionUID = 1L;
  /**
   * An Enum.
   */
  public enum FirstDay { 
   /**
    * An Enum.
    */
    SUNDAY, 
   /**
     * An Enum.
     */
    MONDAY, 
   /**
    * An Enum.
    */
    TUESDAY, 
   /**
    * An Enum.
    */
    WEDNESDAY, 
   /**
    * An Enum.
    */
    THURSDAY, 
   /**
    * An Enum.
    */
    FRIDAY, 
   /**
    * An Enum.
    */
    SATURDAY
  }
  /**
   * An Enum.
   */
  public enum WeekMode { 
    /**
     * An Enum.
     */
    fixed, 
    /**
     * An Enum.
     */
    liquid, 
    /**
     * An Enum.
     */
    variable
    /**
     * An Enum.
     */
  } 

  private Option<Header> header = new Option<Header>("header", Header.DEFAULT);

  private Option<FirstDay> firstDay = new EnumOption<FirstDay>("firstDay", FirstDay.SUNDAY);

  private Option<Boolean> isRTL = new Option<Boolean>("isRTL", false);

  private Option<Boolean> weekends = new Option<Boolean>("weekends", true);

  private Option<WeekMode> weekMode = new EnumOption<WeekMode>("weekMode", WeekMode.fixed, 
      EnumOption.Mode.NAME);

  private Option<Integer> height = new Option<Integer>("height");

  private Option<Integer> contentHeight = new Option<Integer>("contentHeight");

  private Option<Float> aspectRatio = new Option<Float>("aspectRatio", 1.00f);

  private Set<EventSource> eventSources = new HashSet<EventSource>();
  /**
   * Gets the header;.
   * @return the header.
   */
  public Option<Header> getHeader() { 
    return header;
  } 
  /**
   * Sets the header.
   * @param header the new header.
   */
  public void setHeader(Header header) { 
    this.header.setValue(header);
  } 
  /**
   * Returns the first day.
   * @return the first day.
   */
  public Option<FirstDay> getFirstDay() { 
    return firstDay;
  } 
  /**
   * Sets the first day.
   * @param firstDay the first day.
   */
  public void setFirstDay(FirstDay firstDay) { 
    this.firstDay.setValue(firstDay);
  } 
  /**
   * Checks the RTL var.
   * @return RTL.
   */
  public Option<Boolean> getIsRTL() { 
    return isRTL;
  } 
  /**
   * Sets RTL.
   * @param isRTL RTL.
   */
  public void setIsRTL(boolean isRTL) { 
    this.isRTL.setValue(isRTL);
  } 
 /**
  * Returns the weekends.
  * @return the weekend.
  */
  public Option<Boolean> getWeekends() { 
    return weekends;
  } 
  /**
   * Sets the weekends.
   * @param weekends weekends.
   */
  public void setWeekends(Boolean weekends) { 
    this.weekends.setValue(weekends);
  } 
  /**
   * Returns the weekMode.
   * @return weekMode.
   */
  public Option<WeekMode> getWeekMode() { 
    return weekMode;
  } 
  /**
   * Sets the weekMode.
   * @param weekMode weekMode.
   */
  public void setWeekMode(WeekMode weekMode) { 
    this.weekMode.setValue(weekMode);
  } 
  /**
   * Returns the height.
   * @return height.
   */
  public Option<Integer> getHeight() { 
    return height;
  } 
  /**
   * Sets the height.
   * @param height height.
   */
  public void setHeight(Integer height) { 
    this.height.setValue(height);
  } 
  /**
   * Returns content height.
   * @return height.
   */
  public Option<Integer> getContentHeight() { 
    return contentHeight;
  } 
 /**
  * Sets content height.
  * @param contentHeight height.
  */
  public void setContentHeight(Integer contentHeight) { 
    this.contentHeight.setValue(contentHeight);
  } 
  /**
   * Returns aspect ratio.
   * @return aspect ratio.
   */
  public Option<Float> getAspectRatio() { 
    return aspectRatio;
  } 
  /**
   * Sets the aspect ratio.
   * @param aspectRatio aspect ratio.
   */
  public void setAspectRatio(Float aspectRatio) { 
    this.aspectRatio.setValue(aspectRatio);
  } 
  /**
   * Adds a new EventSource.
   * @param source an EventSource.
   */
  public void addEventSource(EventSource source) { 
    eventSources.add(source);
  } 

  /**
   * Builds a JsonString.
   * @return the completed JsonString.
   */
  public String asJsonString() { 
    StringBuilder sb = new StringBuilder();
    sb.append(optionToJson(header));
    sb.append(optionToJson(firstDay));
    sb.append(optionToJson(isRTL));
    sb.append(optionToJson(weekends));
    sb.append(optionToJson(weekMode));
    sb.append(optionToJson(height));
    sb.append(optionToJson(contentHeight));
    sb.append(optionToJson(aspectRatio));

    sb.append("eventSources: [");
    for (EventSource source : eventSources) { 
      sb.append(source.asJsonString()).append(",");
    } 
    sb.append("]");
    return sb.toString();
  } 
  /**
   * Converts an option to a JsonString.
   * @param option thing to convert.
   * @return as a JsonString
   */
  private String optionToJson(Option<?> option) { 
    return option.hasValue() ? option.asJsonString() + "," : "";
  } 
} 
